package com.example.zxx.springboot3.util;

import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * IMapIfUtil:mapIf工具类
 *
 * @author zhangxiaoxiang
 * @date 2022年2月4日
 */
public interface MapIfUtil {

    MapIfUtil BUILD = new MapIfUtil() {
    };

    /**
     * map根据key获取value,无key默认返回null
     *
     * @param key     key
     * @param ruleMap map规则(containsKey)
     * @param <K>     请求参数
     * @param <R>     返回值类型
     * @return 返回值
     */
    default <K, R> R mapIfFunDefaultNull(K key, Map<K, Function<K, R>> ruleMap) {
        return mapIfFunDefaultVal(key, null, ruleMap);
    }

    /**
     * map根据key获取value,无key默认返回给定的默认值
     *
     * @param key        key
     * @param defaultVal 给定的默认值
     * @param ruleMap    map规则(containsKey)
     * @param <K>        请求参数
     * @param <R>        返回值类型
     * @return 返回值
     */
    default <K, R> R mapIfFunDefaultVal(K key, R defaultVal, Map<K, Function<K, R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).apply(key) : defaultVal;
    }

    /**
     * map根据key获取value,无key默认返回给定的逻辑处理结果的值
     *
     * @param key        key
     * @param defaultFun 给定的逻辑处理结果的值
     * @param ruleMap    map规则(containsKey)
     * @param <K>        请求参数
     * @param <R>        返回值类型
     * @return 返回值
     */
    default <K, R> R mapIfFunDefaultFun(K key, Function<K, R> defaultFun, Map<K, Function<K, R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).apply(key) : defaultFun.apply(key);
    }

    /**
     * 判断key的value是否为空
     *
     * @param key     key
     * @param ruleMap 判断规则
     * @param <K>     请求参数类型
     */
    default <K> void mapIfVoid(K key, Map<K, Consumer<K>> ruleMap) {
        if (ruleMap.containsKey(key)) {
            ruleMap.get(key).accept(key);
        }
    }

    /**
     * 判断key满足条件执行map的value逻辑,不满足执行默认逻辑
     *
     * @param key        key
     * @param defaultFun 默认逻辑
     * @param ruleMap    map的value逻辑
     * @param <K>        请求参数
     */
    default <K> void mapIfVoidDefault(K key, Consumer<K> defaultFun, Map<K, Consumer<K>> ruleMap) {
        ruleMap.getOrDefault(key, defaultFun).accept(key);
    }

    /**
     * 请求执行逻辑得到返回值,默认返Null
     *
     * @param key     key
     * @param ruleMap map判断规则
     * @param <K>     请求类型
     * @param <R>     返回值类型
     * @return 返回值
     */
    default <K, R> R mapIfGetDefaultNull(K key, Map<K, Supplier<R>> ruleMap) {
        return mapIfGetDefaultVal(key, null, ruleMap);
    }

    default <K, R> R mapIfGetDefaultVal(K key, R defaultVal, Map<K, Supplier<R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).get() : defaultVal;
    }

    default <K, R> R mapIfGetDefaultGet(K key, Supplier<R> defaultGet, Map<K, Supplier<R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).get() : defaultGet.get();
    }

    default <K, P, R> R mapIfFunDefaultNullByKey(P param, K key, Map<K, Function<P, R>> ruleMap) {
        return mapIfFunDefaultValByKey(param, key, null, ruleMap);
    }

    default <K, P, R> R mapIfFunDefaultValByKey(P param, K key, R defaultVal, Map<K, Function<P, R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).apply(param) : defaultVal;
    }

    default <K, P, R> R mapIfFunDefaultFunByKey(P param, K key, Function<P, R> defaultFun, Map<K, Function<P, R>> ruleMap) {
        return ruleMap.containsKey(key) ? ruleMap.get(key).apply(param) : defaultFun.apply(param);
    }

    default <K, P> void mapIfVoidByKey(P param, K key, Map<K, Consumer<P>> ruleMap) {
        if (ruleMap.containsKey(key)) {
            ruleMap.get(key).accept(param);
        }
    }

    default <K, P> void mapIfVoidDefaultByKey(P param, K key, Consumer<P> defaultFun, Map<K, Consumer<P>> ruleMap) {
        ruleMap.getOrDefault(key, defaultFun).accept(param);
    }

    default <K, P, R> R mapIfFunDefaultNullByField(P param, Function<P, K> fieldKey, Map<K, Function<P, R>> ruleMap) {
        return mapIfFunDefaultValByField(param, fieldKey, null, ruleMap);
    }

    default <K, P, R> R mapIfFunDefaultValByField(P param, Function<P, K> fieldKey, R defaultVal, Map<K, Function<P, R>> ruleMap) {
        K k = fieldKey.apply(param);
        return ruleMap.containsKey(k) ? ruleMap.get(k).apply(param) : defaultVal;
    }

    default <K, P, R> R mapIfFunDefaultFunByField(P param, Function<P, K> fieldKey, Function<P, R> defaultFun, Map<K, Function<P, R>> ruleMap) {
        K k = fieldKey.apply(param);
        return ruleMap.containsKey(k) ? ruleMap.get(k).apply(param) : defaultFun.apply(param);
    }

    default <K, P> void mapIfVoidByField(P param, Function<P, K> fieldKey, Map<K, Consumer<P>> ruleMap) {
        K k = fieldKey.apply(param);
        if (ruleMap.containsKey(k)) {
            ruleMap.get(k).accept(param);
        }
    }

    default <K, P> void mapIfVoidDefaultByField(P param, Function<P, K> fieldKey, Consumer<P> defaultFun, Map<K, Consumer<P>> ruleMap) {
        K k = fieldKey.apply(param);
        ruleMap.getOrDefault(k, defaultFun).accept(param);
    }
}